import static org.junit.Assert.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import org.junit.Before;
import org.junit.Test;

import msigraphx.gibbsSampler.CondDistr;
import msigraphx.gibbsSampler.RandomVariableValue;
import msigraphx.gibbsSampler.VarDistr;
import msigraphx.graph.BayesianNetwork;
import msigraphx.graph.NetworkVertex;


public class DSeparationTest1 {

	BayesianNetwork bayesianNetwork;
	
	@Before
	public void setUp() throws Exception {
		bayesianNetwork = new BayesianNetwork();
		NetworkVertex vertex1 = new NetworkVertex(0, "vertex1");
		NetworkVertex vertex2 = new NetworkVertex(1, "vertex2");
		NetworkVertex vertex3 = new NetworkVertex(2, "vertex3");
		NetworkVertex vertex4 = new NetworkVertex(3, "vertex4");
		NetworkVertex vertex5 = new NetworkVertex(4, "vertex5");
		NetworkVertex vertex6 = new NetworkVertex(5, "vertex6");
		
		vertex1.addAllowedValue(new RandomVariableValue<String>(vertex1, "vertex1Val1"));
		vertex1.addAllowedValue(new RandomVariableValue<String>(vertex1, "vertex1Val2"));

		vertex2.addAllowedValue(new RandomVariableValue<String>(vertex2, "vertex2Val1"));
		vertex2.addAllowedValue(new RandomVariableValue<String>(vertex2, "vertex2Val2"));

		vertex3.addAllowedValue(new RandomVariableValue<String>(vertex3, "vertex3Val1"));
		vertex3.addAllowedValue(new RandomVariableValue<String>(vertex3, "vertex3Val2"));

		vertex4.addAllowedValue(new RandomVariableValue<String>(vertex4, "vertex4Val1"));
		vertex4.addAllowedValue(new RandomVariableValue<String>(vertex4, "vertex4Val2"));

		vertex5.addAllowedValue(new RandomVariableValue<String>(vertex5, "vertex5Val1"));
		vertex5.addAllowedValue(new RandomVariableValue<String>(vertex5, "vertex5Val2"));

		vertex6.addAllowedValue(new RandomVariableValue<String>(vertex6, "vertex6Val1"));
		vertex6.addAllowedValue(new RandomVariableValue<String>(vertex6, "vertex6Val2"));
		
		vertex2.addParent(vertex1);
		vertex2.addParent(vertex3);
		vertex2.addParent(vertex5);
		vertex3.addParent(vertex4);
		vertex4.addParent(vertex5);
		vertex4.addParent(vertex6);
		
		List<RandomVariableValue<String>> emptyDependantList = new Vector<RandomVariableValue<String>>();
		
		vertex1.setCondDistrRow(vertex1.getAllowedValue(0), 0.1f, emptyDependantList);
		vertex1.setCondDistrRow(vertex1.getAllowedValue(1), 0.9f, emptyDependantList);
		
		vertex2.setCondDistrRow(vertex2.getAllowedValue(0), 0.1f, emptyDependantList);
		vertex2.setCondDistrRow(vertex2.getAllowedValue(1), 0.9f, emptyDependantList);
		
		vertex3.setCondDistrRow(vertex3.getAllowedValue(0), 0.1f, emptyDependantList);
		vertex3.setCondDistrRow(vertex3.getAllowedValue(1), 0.9f, emptyDependantList);
		
		vertex4.setCondDistrRow(vertex4.getAllowedValue(0), 0.1f, emptyDependantList);
		vertex4.setCondDistrRow(vertex4.getAllowedValue(1), 0.9f, emptyDependantList);
		
		vertex5.setCondDistrRow(vertex5.getAllowedValue(0), 0.1f, emptyDependantList);
		vertex5.setCondDistrRow(vertex5.getAllowedValue(1), 0.9f, emptyDependantList);
		
		vertex6.setCondDistrRow(vertex6.getAllowedValue(0), 0.1f, emptyDependantList);
		vertex6.setCondDistrRow(vertex6.getAllowedValue(1), 0.9f, emptyDependantList);
		
		
		bayesianNetwork.addVertex(vertex1);
		bayesianNetwork.addVertex(vertex2);
		bayesianNetwork.addVertex(vertex3);
		bayesianNetwork.addVertex(vertex4);
		bayesianNetwork.addVertex(vertex5);
		bayesianNetwork.addVertex(vertex6);
	}
	
	@Test
	public void test1() {
		List<String> fromVertexesLab = new Vector<String>();
		List<String> toVertexesLab = new Vector<String>();
		List<String> observVertexesLab = new Vector<String>();
		
		fromVertexesLab.add("vertex1");
		toVertexesLab.add("vertex6");
		
		boolean dSeparated = bayesianNetwork.computeDSeparation(fromVertexesLab, toVertexesLab, observVertexesLab);
		System.out.println("dSeparated = "+dSeparated);
		
		assertTrue(dSeparated);
	}
	
	@Test
	public void test2() {
		List<String> fromVertexesLab = new Vector<String>();
		List<String> toVertexesLab = new Vector<String>();
		List<String> observVertexesLab = new Vector<String>();
		
		fromVertexesLab.add("vertex1");
		toVertexesLab.add("vertex6");
		observVertexesLab.add("vertex2");
		
		boolean dSeparated = bayesianNetwork.computeDSeparation(fromVertexesLab, toVertexesLab, observVertexesLab);
		System.out.println("dSeparated = "+dSeparated);
		
		assertTrue(!dSeparated);
	}
	
	@Test
	public void test3() {
		List<String> fromVertexesLab = new Vector<String>();
		List<String> toVertexesLab = new Vector<String>();
		List<String> observVertexesLab = new Vector<String>();
		
		fromVertexesLab.add("vertex1");
		toVertexesLab.add("vertex6");
		observVertexesLab.add("vertex2");
		observVertexesLab.add("vertex3");
		
		boolean dSeparated = bayesianNetwork.computeDSeparation(fromVertexesLab, toVertexesLab, observVertexesLab);
		System.out.println("dSeparated = "+dSeparated);
		
		assertTrue(!dSeparated);
	}

}
